home *** CD-ROM | disk | FTP | other *** search
/ Workbench Design / WB Collection.iso / datatypes / mrekodt / src / dispatch.c < prev    next >
C/C++ Source or Header  |  1996-04-07  |  7KB  |  239 lines

  1. /*
  2. **    dispatch.c - dispatcher for REKO DataType class
  3. **    Copyright © 1995 Michael Letowski
  4. */
  5.  
  6. #include <exec/types.h>
  7. #include <exec/memory.h>
  8. #include <dos/dos.h>
  9. #include <graphics/displayinfo.h>
  10. #include <graphics/gfx.h>
  11. #include <graphics/modeid.h>
  12. #include <intuition/classes.h>
  13. #include <datatypes/datatypesclass.h>
  14. #include <datatypes/pictureclass.h>
  15. #include <utility/hooks.h>
  16. #include <support/types.h>
  17.  
  18. #include <string.h>
  19.  
  20. #include <proto/dos.h>
  21. #include <proto/exec.h>
  22. #include <proto/datatypes.h>
  23. #include <proto/graphics.h>
  24. #include <proto/intuition.h>
  25. #include <proto/utility.h>
  26.  
  27. #include "classbase.h"
  28. #include "dispatch.h"
  29.  
  30. #define HCNT        13                                                            /* Number of cards horizontally */
  31. #define VCNT        4                                                                /* Number of cards vertically */
  32. #define REKO_I    55                                                            /* Cards in REKO I cardset */
  33. #define REKO_II    59                                                            /* Cards in REKO II cardset */
  34.  
  35. struct Map
  36. {
  37.     ULONG map_X;
  38.     ULONG map_Y;
  39. };
  40.  
  41. STATIC ASM Object *Dispatch(R_A0 Class *cl, R_A2 Object *o, R_A1 Msg msg);
  42. //STATIC ASM LBOOL GetREKO(R_A6 struct ClassBase *cb, R_A0 Class *cl,
  43. //                                                    R_A2 Object *o, R_A1 struct TagItem *attrs);
  44. STATIC LBOOL GetREKO(struct ClassBase *cb, Object *o, struct TagItem *attrs);
  45. STATIC VOID GetXY(ULONG num, ULONG *x, ULONG *y);
  46. STATIC ULONG LocSetDTAttrs(struct ClassBase *cb, Object *o, ULONG data, ...);
  47. STATIC ULONG LocGetDTAttrs(struct ClassBase *cb, Object *o, ULONG data, ...);
  48.  
  49. Class *InitClass(struct ClassBase *cb)
  50. {
  51.     Class *CL;
  52.  
  53.     /* Create our class (no instance) */
  54.     if(CL=MakeClass(REKODTCLASS,PICTUREDTCLASS,NULL,NULL,0))
  55.     {
  56.         CL->cl_Dispatcher.h_Entry=(HOOKFUNC)Dispatch;
  57.         CL->cl_UserData=(ULONG)cb;
  58.         AddClass(CL);
  59.     }
  60.     return(CL);
  61. }    /* InitClass */
  62.  
  63. STATIC ASM Object *Dispatch(R_A0 Class *cl, R_A2 Object *o, R_A1 Msg msg)
  64. {
  65.     struct ClassBase *cb=(struct ClassBase *)cl->cl_UserData;
  66.     Object *Obj;
  67.  
  68.     switch(msg->MethodID)
  69.     {
  70.         case OM_NEW:                                                                /* We know this method */
  71.             if(Obj=(Object *)DoSuperMethodA(cl,o,msg))
  72.                 unless(GetREKO(cb,Obj,((struct opSet *)msg)->ops_AttrList))
  73.                 {
  74.                     CoerceMethod(cl,Obj,OM_DISPOSE);
  75.                     return(NULL);
  76.                 }
  77.             break;
  78.         default:                                                                        /* Let the superclass handle it */
  79.             Obj=(Object *)DoSuperMethodA(cl,o,msg);
  80.             break;
  81.     }
  82.     return(Obj);
  83. }
  84.  
  85. STATIC LBOOL GetREKO(struct ClassBase *cb, Object *o, struct TagItem *attrs)
  86. {
  87.     struct RekoHeader Header;
  88.     struct BitMapHeader *BMHD=NULL;
  89.     struct BitMap *BM;
  90.     struct ColorRegister *CMAP=NULL;
  91.     LONG *CRegs=NULL;
  92.  
  93.     MPTR Buffer,SrcPtr;                                                        /* Buffer for reading */
  94.     STRPTR Title;                                                                    /* Picture name */
  95.     BPTR FH=0;                                                                        /* File handle */
  96.     ULONG ModeID;                                                                    /* Display mode */
  97.     ULONG HCnt,Cards,Height,Width,Depth,LSize,CSize;
  98.     ULONG BPR,DstOffs,X,Y,I,J,K;
  99.  
  100.     /* Get default title */
  101.     Title=(STRPTR)GetTagData(DTA_Name,NULL,attrs);
  102.  
  103.     /* Get file handle and BitMapHeader */
  104.     LocGetDTAttrs(cb,o,DTA_Handle,&FH,PDTA_BitMapHeader,&BMHD,TAG_DONE);
  105.     try(FH && BMHD,    EXIT)                                                    /* File handle or header not supplied */
  106.     try(Seek(FH,0,OFFSET_BEGINNING)>=0,    EXIT);        /* Position at the beginnig of file */
  107.     try(Read(FH,&Header,HEADER_SIZE)==HEADER_SIZE,    EXIT);
  108.     if(Header.rh_ID!=REKO_ID)                                            /* Not REKO */
  109.     {
  110.         SetIoErr(ERROR_OBJECT_WRONG_TYPE);                    /* Inform caller */
  111.         throw(EXIT);
  112.     }
  113.  
  114.     /* Calculate sizes */
  115.     Width=Header.rh_Width;
  116.     Height=Header.rh_Height;
  117.     Depth=Header.rh_Depth;
  118.     Cards=Header.rh_Cards;
  119.     LSize=Width>>3;                                                                /* Width in bytes */
  120.     CSize=LSize*Height*Depth;                                            /* Card size in bytes */
  121.     if(Header.rh_SingleSize!=CSize ||
  122.             Header.rh_BodySize!=CSize*Cards+CTABLE_SIZE || Cards==0)
  123.     {                                                                                            /* Do internal checking */
  124.         SetIoErr(ERROR_OBJECT_WRONG_TYPE);                    /* Inform caller */
  125.         throw(EXIT);
  126.     }
  127.  
  128.     /* Calculate number of horizonatal cards */
  129.     HCnt=(Cards==REKO_I) ? 14 : 
  130.                 ((Cards==REKO_II) ? 16 : Cards/VCNT+(Cards%VCNT>0));
  131.     BMHD->bmh_Width=Width*HCnt;                                        /* Fill in informations */
  132.     BMHD->bmh_Height=Height*VCNT;
  133.     BMHD->bmh_Depth=Depth;
  134.  
  135.     /* Get display mode id */
  136.     if(ModeNotAvailable(Header.rh_ModeID)==0)            /* Good mode */
  137.         ModeID=Header.rh_ModeID;
  138.     else                                                                                    /* Calculate mode */
  139.     {
  140.         ModeID=BestModeID(BIDTAG_DIPFMustHave,    DIPF_IS_HAM,
  141.                                             BIDTAG_DesiredWidth,    BMHD->bmh_Width,
  142.                                             BIDTAG_DesiredHeight,    BMHD->bmh_Height,
  143.                                             BIDTAG_Depth,                    BMHD->bmh_Depth,
  144.                                             BIDTAG_SourceID,            HIRESHAMLACE_KEY,TAG_DONE);
  145.         if(ModeID==INVALID_ID)
  146.             ModeID=HIRESHAMLACE_KEY;
  147.     }
  148.  
  149.     /* Get colors */
  150.     LocSetDTAttrs(cb,o,PDTA_NumColors,1<<BMHD->bmh_Depth,TAG_DONE);
  151.     LocGetDTAttrs(cb,o,PDTA_ColorRegisters,&CMAP,PDTA_CRegs,&CRegs,TAG_DONE);
  152.     try(CMAP && CRegs,    EXIT);
  153.     try(Read(FH,CMAP,CTABLE_SIZE)==CTABLE_SIZE,    EXIT);
  154.     /* Set remap palette */
  155.     for(I=0; I<1<<BMHD->bmh_Depth; I++)
  156.     {
  157.         CRegs[I*3+0]=CMAP[I].red<<24;
  158.         CRegs[I*3+1]=CMAP[I].green<<24;
  159.         CRegs[I*3+2]=CMAP[I].blue<<24;
  160.     }
  161.  
  162.     /* Prepare bitmap */
  163.     try(BM=AllocBitMap(BMHD->bmh_Width,BMHD->bmh_Height,BMHD->bmh_Depth,
  164.                                             BMF_CLEAR | BMF_INTERLEAVED | BMF_DISPLAYABLE,NULL),
  165.             NO_BITMAP);
  166.     BPR=BM->BytesPerRow;
  167.  
  168.     /* Read data */
  169.     try(Buffer=AllocVec(CSize,MEMF_PUBLIC),    NO_MEM);
  170.     for(I=0; I<Cards; I++)
  171.     {
  172.         try(Read(FH,Buffer,CSize)==CSize,            BODY_ERR);
  173.         GetXY(I,&X,&Y);                                                            /* Get coordinates */
  174.         SrcPtr=Buffer;
  175.         DstOffs=Y*Height*BPR+X*LSize;
  176.         for(J=0; J<Height; J++)
  177.         {
  178.             for(K=0; K<Depth; K++)
  179.             {
  180.                 memcpy(BM->Planes[K]+DstOffs,SrcPtr,LSize);
  181.                 SrcPtr+=LSize;
  182.             }
  183.             DstOffs+=BPR;
  184.         }
  185.     }
  186.     FreeVec(Buffer);
  187.     
  188.     /* Set attributes of destination picture */
  189.     LocSetDTAttrs(cb,o,DTA_ObjName,Title,
  190.                                             DTA_NominalHoriz,    BMHD->bmh_Width,
  191.                                             DTA_NominalVert,    BMHD->bmh_Height,
  192.                                             PDTA_BitMap,            BM,
  193.                                             PDTA_ModeID,            ModeID,
  194.                                             TAG_DONE);
  195.     return(TRUE);
  196.  
  197.     /* Exceptions */
  198.     except(BODY_ERR,    );
  199.     except(NO_MEM,        FreeVec(Buffer));
  200.     except(NO_BITMAP,    FreeBitMap(BM));
  201.     except(EXIT,            );
  202.     return(FALSE);
  203. }    /* GetREKO */
  204.  
  205. STATIC VOID GetXY(ULONG num, ULONG *x, ULONG *y)
  206. {
  207.     STATIC CONST struct Map Mapping[]=
  208.     {
  209.         {HCNT,0},    {HCNT,1},        {HCNT,1},
  210.         {HCNT,3},    {HCNT+1,3},    {HCNT+2,3},    {HCNT,2}
  211.     };
  212.  
  213.     if(num<3)
  214.     {
  215.         *x=Mapping[num].map_X;
  216.         *y=Mapping[num].map_Y;
  217.     }
  218.     else if(num>54 && num<59)
  219.     {
  220.         *x=Mapping[num-52].map_X;
  221.         *y=Mapping[num-52].map_Y;
  222.     }
  223.     else
  224.     {
  225.         *x=(num-3)/VCNT;
  226.         *y=(num-3)%VCNT;
  227.     }
  228. }    /* GetXY */
  229.  
  230. STATIC ULONG LocSetDTAttrs(struct ClassBase *cb, Object *o, ULONG data, ...)
  231. {
  232.     return(SetDTAttrsA(o,NULL,NULL,(struct TagItem *)&data));
  233. }    /* LocSetDTAttrs */
  234.  
  235. STATIC ULONG LocGetDTAttrs(struct ClassBase *cb, Object *o, ULONG data, ...)
  236. {
  237.     return(GetDTAttrsA(o,(struct TagItem *)&data));
  238. }    /* LocGetDTAttrs */
  239.